﻿using System;
using System.IO;
using System.Collections.Generic;
using System.Net;

namespace AIC_Notification
{
    public class BaseReport
    {
        // Setup e-mail
        public IList<string> toRecipients { get; set; }
        public IList<string> ccRecipients { get; set; }
        public string SubjectID { get; set; }

        // Setup file
        public string FileName { get; set; }

        public BaseReport()
        {
            toRecipients = new List<string>();
            ccRecipients = new List<string>();
            SubjectID = "";
            FileName = "Report.htm";
        }

        public virtual void SendReportAsEmail()
        {
        }
    }

    public class FormatedReport: BaseReport
    {
        // HTML Body Information
        public string HeaderInformation { get; set; }
        public string ReportTitle { get; set; }
        public bool IsEmptyBody = false;
        public int TableWidthPercent { get; set; }

        private static string BJScoreUrl = WebUtility.HtmlEncode("https://jqedu.sharepoint.cn/Beijing/_layouts/15/guestaccess.aspx?guestaccesstoken=1ZNF1AuFsqCxE6Axe%2bCZtlVab2zVrGPWg%2f%2f4DC97WqE%3d&docid=2_1aec1c616260847a2b3b6d4a8c083e585&rev=1");
        private static string CDScoreUrl = WebUtility.HtmlEncode("https://jqedu.sharepoint.cn/Chengdu/_layouts/15/guestaccess.aspx?guestaccesstoken=JrZsBAJCRFVXo9DfI2nZbzuiA%2bLtThABnj5EZJ8rBRI%3d&docid=2_137f89f26caee4711ba76d4aa4afb0e09&rev=1");
        private static string HZScoreUrl = WebUtility.HtmlEncode("https://jqedu.sharepoint.cn/Hangzhou/_layouts/15/guestaccess.aspx?guestaccesstoken=jMjYSH%2biHWhAjwd54qjnUAASZbo%2f%2bvj1PkpTiriktQk%3d&docid=2_1b13aa39ed6914130a04be024afddddb2&rev=1");
        private static string SHScoreUrl = WebUtility.HtmlEncode("https://jqedu.sharepoint.cn/Shanghai/_layouts/15/guestaccess.aspx?guestaccesstoken=W5JdqG0GK0fQ5Lkb7eyedEVQr7YoZGHAvQuasfUZqhQ%3d&docid=2_128a99d6b15454246ad9b7f56061bae5e&rev=1");
        private static string SZScoreUrl = WebUtility.HtmlEncode("https://jqedu.sharepoint.cn/Shenzhen/_layouts/15/guestaccess.aspx?guestaccesstoken=UVX1%2bqWkFn0lokWXzas813IaXJS5t8jdQqAb1R5n%2fTk%3d&docid=2_19cd26a0474e04aff86051cb846557142&rev=1");
        private static string XAScoreUrl = WebUtility.HtmlEncode("https://jqedu.sharepoint.cn/Xian/_layouts/15/guestaccess.aspx?guestaccesstoken=7qGJxkm%2f97yWMFOpRgaVPtiaFikgRCzj33%2bDYovch5w%3d&docid=2_1f97a19e3b1524d40b7cbdec00d09aaa6&rev=1");

        public FormatedReport()
        {
            HeaderInformation = "";
            ReportTitle = "Default Report";
            TableWidthPercent = 0;
        }

        public void AddAcademicManagerEmail(string AM)
        {
            Teacher AcademicManager = null;

            AcademicManager = TeacherDB.GetTeacherByName(AM);
            if (AcademicManager != null)
                toRecipients.Add(AcademicManager.Email);
            else
                Global.SysUtil.Log(String.Format("Academic Manager \"{0}\" not found", AM), 2);
        }

        private string GenerateXHTMLHeader()
        {
            string xhtmlHeader = "";

            xhtmlHeader = "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">";
            xhtmlHeader += "<html xmlns=\"http://www.w3.org/1999/xhtml\">";
            xhtmlHeader += "<head>";
            xhtmlHeader += "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />";
            xhtmlHeader += "<title>AIC Notification</title>";
            xhtmlHeader += "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"/>";
            xhtmlHeader += "<style>";
            xhtmlHeader += "table, th, td { border: 1px solid #AAAAAA; border-collapse: collapse;}";
            xhtmlHeader += "th, td { padding: 2px 8px 2px 8px; text-align: center; font-family:helvetica ,sans-serif; }";
            xhtmlHeader += "</style>";
            xhtmlHeader += "</head>";

            return xhtmlHeader;
        }

        private string GenerateXHTMLFooter()
        {
            return "</html>";
        }

        public void SetWidth(int percent)
        {
            TableWidthPercent = percent;
        }

        public virtual string GenerateHeader()
        {
            // Popular Body
            string htmlBody = "<body>";
            htmlBody += String.Format("<table align=\"center\" style=\"margin-left:auto; margin-right: auto; border: 1px solid black; border-collapse: collapse; font:italic arial,sans-serif; {0};\">", 
                TableWidthPercent != 0 ? String.Format("width: {0}%;", TableWidthPercent) : "");

            // Information and date
            htmlBody += "<tr><td style=\"background-color: #281557;\">";
            if (HeaderInformation != "")
                htmlBody += String.Format("<p style=\"font-size: 20px; color: white; font-weight: bold;\">{0} - {1:d}</p>", HeaderInformation, Global.Now().Date);
            else
                htmlBody += String.Format("<p style=\"font-size: 20px; color: white; font-weight: bold;\">{0:d}</p>", Global.Now().Date);
            htmlBody += "</td></tr>";

            // Table Title
            htmlBody += "<tr><td style=\"padding: 5px 0 5px 0;\">";
            htmlBody += "<p style=\"font-size: 30px; color: grey; font-weight: normal;\">" + ReportTitle +"</p>";
            htmlBody += "</td></tr>";

            // Insert Ledger if any
            htmlBody += GenerateLedger();

            //Add boarder around inner table
            // htmlBody += "<tr style=\"width: 100%;\"><td style=\"padding: 2px 2px 2px 2px; text-align: center; width: 100%\">";
            htmlBody += "<tr><td style=\"padding: 2px 2px 2px 2px; text-align: center;\">";

            return htmlBody;
        }

        public virtual string InsertStudentName(AIC_Application student, int FontSize, string BackgroudColor = "", int RowSpan = 1)
        {
            string tableBody = "";
            string CRMUrl = "CRM";
            string ScoreUrl = "Score";

            if (student != null)
            {
                if (student.StudentObject != null)
                {
                    string ScoreLink = "";
                    CRMUrl = String.Format("<a href=\"{0}\">CRM</a>", "https://ap2.salesforce.com/" + student.StudentObject.Id);
                    switch (student.StudentObject.GetCity())
                    {
                        case "Beijing":
                            ScoreLink = BJScoreUrl;
                            break;
                        case "Chengdu":
                            ScoreLink = CDScoreUrl;
                            break;
                        case "Hangzhou":
                            ScoreLink = HZScoreUrl;
                            break;
                        case "Shanghai":
                            ScoreLink = SHScoreUrl;
                            break;
                        case "Shenzhen":
                            ScoreLink = SZScoreUrl;
                            break;
                        case "Xian":
                            ScoreLink = XAScoreUrl;
                            break;
                    }
                    ScoreUrl = String.Format("<a title=\"test\" href=\"{0}\">Score</a>", ScoreLink);
                }

                if (BackgroudColor != "")
                    tableBody += String.Format("<td style=\"background-color: {0};\" rowspan=\"{1}\"><div>", BackgroudColor, RowSpan);
                else
                    tableBody += String.Format("<td rowspan=\"{0}\"><div>", RowSpan);

                tableBody += String.Format("<div><div style=\"font-size: {4}px;\"><a href=\"{0}\">{1}</a> <span style=\"font-size: {5}px;\">({2},{3})</span></div></div>", student.Url, student.Name, CRMUrl, ScoreUrl, FontSize, FontSize - 2);
                tableBody += String.Format("<div><div style=\"font-size: {1}px;\">{0}</div></div>", student.AC_PT, FontSize);
                if (student.AC_ST != "")
                    tableBody += String.Format("<div><div style=\"font-size: {1}px;\">{0}</div></div>", student.AC_ST, FontSize);
                tableBody += String.Format("<div><div style=\"font-size: {1}px;\">{0}</div></div>", student.EC, FontSize);
                tableBody += "</div></td>";
            }
            else
            {
                tableBody = "<td></td>";
            }

            return tableBody;
        }

        public virtual string InsertStudentScore(AIC_Application student, int FontSize, bool ShowApplicationYear = false, int RowSpan = 1)
        {
            string tableBody = "";
            string scoreBody = "";
            int ScoreFontSize = FontSize;
            int SubScoreFontSize = FontSize - 2;

            if ((student != null) && (student.StudentObject != null))
            {
                tableBody += String.Format("<td rowspan=\"{0}\">", RowSpan);

                // Display Application Year
                if (ShowApplicationYear)
                {
                    tableBody += String.Format("<div><div style=\"font-size: {0}px;\"><b>Applying:</b> Fall {1}</div></div>",
                            ScoreFontSize,
                            student.StudentObject.ApplicationYear);
                }

                // Insert GPA
                if (student.StudentObject.ScoreObject != null && student.StudentObject.ScoreObject.GPA_Summary != "0")
                {
                    scoreBody += "<div>";
                    scoreBody += String.Format("<div style=\"font-size: {0}px;\"><b>GPA</b>: {1}</div>", ScoreFontSize, student.StudentObject.ScoreObject.GPA_Summary);
                    /*
                    foreach (var GPA in student.StudentObject.ScoreObject.GPAs)
                    {
                        scoreBody += String.Format("<div style=\"font-size: {0}px;\">Grade {1}: {2}/{3} {4}</div>",
                            SubScoreFontSize,
                            GPA.Grade,
                            GPA.GPA,
                            GPA.GPA_Scale,
                            GPA.Weighted ? "W" : "");
                    }
                    */
                    scoreBody += "</div>";
                }
                else
                {
                    tableBody += String.Format("<div style=\"font-size: {0}px;\"><b>GPA</b>: <span style=\"color: orange;\">None</span></div>", ScoreFontSize);
                }

                // Insert SAT
                if (student.StudentObject.ScoreObject != null && student.StudentObject.ScoreObject.SAT_Total() != 0)
                {
                    scoreBody += String.Format("<div><div style=\"font-size: {0}px;\"><b>SAT:</b> {1}</div><div style=\"font-size: {2}px;\">(R:{3}, M:{4})</div></div>",
                        ScoreFontSize, 
                        student.StudentObject.ScoreObject.SAT_Total(), 
                        SubScoreFontSize,
                        student.StudentObject.ScoreObject.SAT_Reading, 
                        student.StudentObject.ScoreObject.SAT_Math);
                }

                // Insert ACT
                if (student.StudentObject.ScoreObject != null && student.StudentObject.ScoreObject.ACT_Composit() != 0)
                {
                    scoreBody += String.Format("<div><div style=\"font-size: {0}px;\"><b>ACT:</b> {1}</div><div style=\"font-size: {2}px;\">(E:{3}, M:{4}, R:{5}, S:{6}, W:{7})</div></div>",
                        ScoreFontSize,
                        student.StudentObject.ScoreObject.ACT_Composit(),
                        SubScoreFontSize,
                        student.StudentObject.ScoreObject.ACT_English,
                        student.StudentObject.ScoreObject.ACT_Math,
                        student.StudentObject.ScoreObject.ACT_Reading,
                        student.StudentObject.ScoreObject.ACT_Science,
                        student.StudentObject.ScoreObject.ACT_Writing);
                }

                if (student.StudentObject.ScoreObject != null && student.StudentObject.ScoreObject.SAT_Total() == 0 && student.StudentObject.ScoreObject.ACT_Composit() == 0)
                {
                    scoreBody += String.Format("<div style=\"font-size: {0}px; color: orange\">No SAT and ACT</div>", ScoreFontSize);
                }

                // Insert TOEFL
                if (student.StudentObject.ScoreObject != null && student.StudentObject.ScoreObject.TOEFL_Total != 0)
                {
                    scoreBody += String.Format("<div><div style=\"font-size: {0}px;\"><b>TOEFL:</b> {1}</div><div style=\"font-size: {2}px;\">(E:{3}, M:{4}, R:{5}, S:{6})</div></div>",
                        ScoreFontSize,
                        student.StudentObject.ScoreObject.TOEFL_Total,
                        SubScoreFontSize,
                        student.StudentObject.ScoreObject.TOEFL_Listening,
                        student.StudentObject.ScoreObject.TOEFL_Reading,
                        student.StudentObject.ScoreObject.TOEFL_Speaking,
                        student.StudentObject.ScoreObject.TOEFL_Writing);
                }
                else
                {
                    scoreBody += String.Format("<div style=\"font-size: {0}px;\"><b>TOEFL:</b> <span style=\"color: orange\">None</span></div>", ScoreFontSize);
                }

                if (student.StudentObject.ScoreObject == null || 
                    (student.StudentObject.ScoreObject.SAT_Total() == 0 && student.StudentObject.ScoreObject.ACT_Composit() == 0 && student.StudentObject.ScoreObject.TOEFL_Total == 0))
                {
                    scoreBody = String.Format("<div style=\"font-size: {0}px; color: orange\">No Score</div>", ScoreFontSize);
                }

                tableBody += scoreBody;
                tableBody += "</td>";
            }
            else
            {
                tableBody += String.Format("<td rowspan=\"{0}\"></td>", RowSpan);
            }

            return tableBody;
        }

        public virtual string InsertSAT2andAP(AIC_Application student, int FontSize, int RowSpan = 1)
        {
            string tableBody = "";
            string scoreBody = "";
            int ScoreFontSize = FontSize;
            int SubScoreFontSize = FontSize - 2;

            if ((student != null) && (student.StudentObject != null))
            {
                tableBody += String.Format("<td rowspan=\"{0}\">", RowSpan);

                if (student.StudentObject.ScoreObject != null && student.StudentObject.ScoreObject.SAT2_Count > 0)
                {
                    scoreBody += "<div>";

                    scoreBody += String.Format("<div style=\"font-size: {0}px;\"><u><b>SAT2:</b> <span style=\"font-size: {1}px;\">{2}, Avg: {3}</span></u></div>",
                        ScoreFontSize,
                        SubScoreFontSize,
                        student.StudentObject.ScoreObject.SAT2_Count,
                        (int)student.StudentObject.ScoreObject.SAT2_Mean);

                    foreach (var SAT2 in student.StudentObject.ScoreObject.SAT2s)
                    {
                        scoreBody += String.Format("<div style=\"font-size: {0}px;\">{1}: {2}</div>",
                            SubScoreFontSize,
                            SAT2.Subject,
                            SAT2.Score != 0 ? SAT2.Score.ToString() : "<span style=\"color: orange\">Pending</span>");
                    }

                    scoreBody += "</div>";
                }

                if (student.StudentObject.ScoreObject != null && student.StudentObject.ScoreObject.AP_Count > 0)
                {
                    scoreBody += "<div>";

                    scoreBody += String.Format("<div style=\"font-size: {0}px;\"><u><b>AP:</b> <span style=\"font-size: {1}px;\">{2}, Avg: {3:0.00}</span></u></div>",
                        ScoreFontSize,
                        SubScoreFontSize,
                        student.StudentObject.ScoreObject.AP_Count,
                        student.StudentObject.ScoreObject.AP_Mean);

                    foreach (var AP in student.StudentObject.ScoreObject.APs)
                    {
                        scoreBody += String.Format("<div style=\"font-size: {0}px;\">{1}: {2}</div>",
                            SubScoreFontSize,
                            AP.Subject,
                            AP.Score != 0 ? AP.Score.ToString() : "<span style=\"color: orange\">Pending</span>");
                    }

                    scoreBody += "</div>";
                }

                tableBody += scoreBody;
                tableBody += "</td>";
            }
            else
            {
                tableBody += String.Format("<td rowspan=\"{0}\"></td>", RowSpan);
            }

            return tableBody;

        }

        public virtual string GenerateLedger()
        {
            return "";
        }

        public virtual string GenerateFooter()
        {
            string htmlBody = "";

            // Finish inner table
            htmlBody += "</td></tr>";

            // Insert footer
            htmlBody += "<tr><td style=\"background-color: #D5E2F7; padding: 10px 0 10px 0;\">";
            htmlBody += "<p style=\"font-size: 15px; color: grey; font-weight: normal; text-align:center;\">AIC Education</p>";
            htmlBody += "</td></tr>";

            // Finish body
            htmlBody += "</table>";
            htmlBody += "</body>";

            return htmlBody;
        }

        public virtual string GenerateBody()
        {
            string innerTableHeader = "";
            string innerTableBody = GenerateInnerTable();
            string innerTableFooter = "";

            innerTableHeader += "<table align=\"center\" sytle=\"width: 100%;\">";
            if (innerTableBody != "")
            {
                innerTableHeader += InnerTableHeader();
                IsEmptyBody = false;
            }
            else
            {
                innerTableBody += EmptyInnerTable();
                IsEmptyBody = true;
            }
            innerTableFooter += "</table>";

            return innerTableHeader + innerTableBody + innerTableFooter;
        }

        public virtual string GenerateInnerTable()
        {
            return "";
        }

        public virtual string InnerTableHeader()
        {
            return "";
        }

        public virtual string EmptyInnerTable()
        {
            return "<tr><td style=\"padding: 10px 0 10px 0; text-align:center;\">Empty Report</td></tr>";
        }

        public virtual string GetSubject()
        {
            return ReportTitle;
        }

        public string GetHTMLBody()
        {
            string ReportBody = "";
            string FormattedHTML = "";

            string InnerBody = GenerateBody();

            ReportBody += GenerateXHTMLHeader();
            ReportBody += GenerateHeader();
            ReportBody += InnerBody;
            ReportBody += GenerateFooter();
            ReportBody += GenerateXHTMLFooter();

            FormattedHTML = System.Xml.Linq.XElement.Parse(ReportBody).ToString();

            return FormattedHTML;
        }

        public void SaveReportToFile(string FileName, string HTMLBody)
        {
            string FormatedFileName;

            // Build file name
            FormatedFileName = FileName;
            FormatedFileName.Replace(' ', '_'); // replace space with underscore
            Global.SysUtil.Log("Saving file as: " + FormatedFileName);
            FileName = FormatedFileName;

            if (!Directory.Exists(Global.OutputDirectory))
                Directory.CreateDirectory(Global.OutputDirectory);

            using (StreamWriter sw = new StreamWriter(Global.OutputDirectory + FileName))
            {
                sw.WriteLine(HTMLBody);
            }
        }
    }
}
